package pkg16b_eca.SQL.Tables;

import java.util.ArrayList;
import java.util.HashMap;
import pkg16b_eca.SQL.Query;
import pkg16b_eca.data.validate.Person;
import pkg16b_eca.data.validate.Text;
import se.oru.informatik.InformatikException;

public class SQLRoll extends Query {
    public SQLRoll() throws InformatikException {}
    
    /** Inserting values into database. */
    public void insert(final String strNamn, final String strBeskrivning, final String strHarfarg, final String strKon, final int intAlder, final int intLangd, final int intVikt, final int intSID, final int intPID) {
        String query = "insert into roll (RID, namn, beskrivning, onskatkon, onskatalder, onskatlangd, onskatvikt, onskatharfarg, SID, PID) values (" + 
                SQLGetAutoIncrement("roll", "RID") + ", '" + Text.getSafeSpecialCharacters(strNamn) + "', '" + Text.getSafeSpecialCharacters(strBeskrivning) + "', " +  Person.getKon(strKon).ordinal() + ", " + intAlder + ", " + intLangd + ", " + intVikt + ", '" + strHarfarg + "', " + intSID + ", " + intPID + ");";
        SQLInsert(query);
    }
    
    /** Inserting values into database. */
    public void update(final int intRID, final String strNamn, final String strBeskrivning, final String strHarfarg, final String strKon, final int intAlder, final int intLangd, final int intVikt, final int intSID, final int intPID) {
        String query = "update roll set " + 
                "namn='" + Text.getSafeSpecialCharacters(strNamn) + "', " +
                "beskrivning='" + Text.getSafeSpecialCharacters(strBeskrivning) + "', " +
                "onskatkon=" +  Person.getKon(strKon).ordinal() + ", " +
                "onskatalder=" + intAlder + ", " + 
                "onskatlangd=" + intLangd + ", " +
                "onskatvikt=" + intVikt + ", " +
                "onskatharfarg='" + strHarfarg + "', " +
                "SID=" + intSID + ", " + 
                "PID=" + intPID + " " + 
                "where RID=" + intRID;
        SQLUpdate(query);
    }
    
    public void replaceSkadespelare(final int whereRID, final int setSID) {
        String query = "update roll set " + 
                "SID=" + setSID + 
                " where RID=" + whereRID;
        SQLUpdate(query);
    }
    
    /** Deleting a value from the database. */
    public void delete(final int intRID) {
        String query = "delete from roll where RID=" + intRID;
        SQLDelete(query);
    }
    
    /** Check if a value exists. */
    public boolean exists(final String RName) {
        String query = SQLSelect("select namn from roll where namn = '" + RName + "'");
        return !query.isEmpty();
    }
    
    /** Check if a value exists. */
    public boolean exists(final int RID) {
        String query = SQLSelect("select RID from roll where RID = '" + RID + "'");
        return !query.isEmpty();
    }
    
    /**Usage Example : Se vilka roller som finns i systemet
     *Variables used: al = ArrayList, s = String
     * ArrayList<String> al = SQL.getRoll().getRoller();
        for (String s : al) {
            System.out.println(s);
        }
     */
    public ArrayList<String> getRoller() {
        return SQLSelectList("select namn from roll");
    }
    
    /** Select a rolls ID from a name. */
    public int getRollRID(String name) {
        return Text.parseNumber(SQLSelect("select roll.rid from roll where roll.namn = '" + name + "'"));
    }
    
    /** Select a förmågas name from an ID. */
    public String getRollName(int RID) {
        return SQLSelect("select roll.namn from roll where roll.rid = " + RID);
    }
    
    /**Usage Example : Se vilka attribut en roll har
     *Variables used: hm = HashMap
        HashMap<String, String> hm = SQL.getRoll().getAttribut("Emma Black");
        System.out.println(hm.values());
     */
    public HashMap<String, String> getAttribut(String rollName) {
        return SQLSelectRow("select * from roll " + 
                "where roll.namn = '" + rollName + "'");
    }
    
    /**Usage Example : Se vilken produktion en roll tillhör
     *Variables used: s = String
       String s = SQL.getRoll().getProduktion("Emma Black");
       System.out.println(s);
     */
    public String getProduktion(String rollName) {
        return SQLSelect("select produktion.titel from produktion " + 
                "join roll on roll.pid = produktion.pid " + 
                "where roll.namn = '" + rollName + "'");
    }
    
    /**Usage Example : Se vilka skådespelare som föreslagits för en given roll
     *Variables used: al = ArrayList, s = String
        ArrayList<String> al = SQL.getRoll().getForeslagnaSkadespelare("Tanyah Lovic");
        for (String s : al) {
            System.out.print(s);
        }
     */
    public ArrayList<String> getForeslagnaSkadespelare(String rollName) {
        return SQLSelectList("select skadespelare.namn from skadespelare " + 
                "join skadepelare_forslagen_roll on skadepelare_forslagen_roll.sid = skadespelare.sid " + 
                "join roll on roll.rid = skadepelare_forslagen_roll.rid " + 
                "where roll.namn ='" + rollName + "'");
    }
    
    /**Usage Example : Se vilka förmågor en roll kräver 
     *Variables used: s = String
        for (String s : SQL.getRoll().getFormagor("Emma Black")) {
            System.out.println(s);
        }
     */
    public ArrayList<String> getFormagor(String rollName) {
        return SQLSelectList("select formaga.namn from formaga " + 
                "join roll_kraver_formaga on roll_kraver_formaga.fid = formaga.fid " + 
                "join roll on roll.rid = roll_kraver_formaga.rid " + 
                "where roll.namn = '" + rollName + "';");
    }
    
    /** Match a roll with a skådespelare. */
    public ArrayList<String> getMatch(final String rollNamn) {
        return getMatch(rollNamn, true, true, true, true, true);
    }
    
    /** Match a roll with a skådespelare. */
    public ArrayList<String> getMatch(final String rollNamn, final boolean alder, final boolean kon, final boolean harfarg, final boolean langd, final boolean vikt) {
        return getMatch(rollNamn, alder, kon, harfarg, langd, vikt, 0);
    }
    
    /** Match a roll with a skådespelare. */
    public ArrayList<String> getMatch(final String rollNamn, final boolean alder, final boolean kon, final boolean harfarg, final boolean langd, final boolean vikt, final int difference) {
        ArrayList<String> result = SQLSelectMatrix("select onskatalder, onskatkon, onskatharfarg, onskatlangd, onskatvikt from roll where namn='" + rollNamn + "'").get(0);
        int rAlder = alder ? Text.parseNumber(result.get(0)) : -1;
        int rKon = kon ? Text.parseNumber(result.get(1)) : -1;
        String rHarfarg = harfarg ? result.get(2) : "";
        int rLangd = langd ? Text.parseNumber(result.get(3)) : -1;
        int rVikt = vikt ? Text.parseNumber(result.get(4)) : -1;
        
        return getMatch(rollNamn, rAlder, rKon, rHarfarg, rLangd, rVikt, difference);
    }
    
    /** Match a roll with a skådespelare. */
    public ArrayList<String> getMatch(final String rollNamn, final int onskatAlder, final int onskatKon, final String onskatHarfarg, final int onskatLangd, final int onskatVikt) {
        return getMatch(rollNamn, onskatAlder, onskatKon, onskatHarfarg, onskatLangd, onskatVikt, 0);
    }
    
    /** Match a roll with a skådespelare.
     * Usage Example : System.out.println(SQL.getRoll().getMatch("John Clark", 28, 0, "", -1, -1, 3)); to get all males that are around 28 years old. In this case the name wouldn't matter.
     * 
     */
    public ArrayList<String> getMatch(final String rollNamn, final int onskatAlder, final int onskatKon, final String onskatHarfarg, final int onskatLangd, final int onskatVikt, final int difference) {
        String sql = ""; //The SQL query that is going to be executed.
        String andOrWhere = " where"; //Since you have to use "and" after the first "where" in SQL, we use a variable as an easy fix.

        if (!rollNamn.isEmpty()) {
            sql += andOrWhere + " lower(roll.namn) like '%" + rollNamn.toLowerCase() + "%'";
            andOrWhere = " and";
        }

        if (onskatAlder >= 0) {
            sql += andOrWhere + " alder>=" + (onskatAlder - difference) + " and alder<=" + (onskatAlder + difference);
            andOrWhere = " and";
        }

        if (onskatKon >= 0) {
            sql += andOrWhere + " kon=" + onskatKon;
            andOrWhere = " and";
        }

        if (!onskatHarfarg.isEmpty()) {
            sql += andOrWhere + " lower(harfarg)='" + onskatHarfarg.toLowerCase() + "'";
            andOrWhere = " and";
        }

        if (onskatLangd >= 0) {
            sql += andOrWhere + " langd>=" + (onskatLangd - difference) + " and langd<=" + (onskatLangd + difference);
            andOrWhere = " and";
        }

        if (onskatVikt >= 0) {
            sql += andOrWhere + " vikt>=" + (onskatVikt - difference) + " and alder<=" + (onskatVikt + difference);
        }
        
        return SQLSelectList("select skadespelare.namn from skadespelare, roll" + sql + ";");
    }
    
    /**Se vilken skådespelare som tidigare spelat en roll 
     System.out.println(getRoll().getSkadespelareTidigareSpelatRoll("Katie Harris"));*/
    public String getSkadespelareTidigareSpelatRoll(String rollNamn) {
        return SQLSelect("select skadespelare.namn from skadespelare" + 
               " join roll on roll.sid = skadespelare.sid" +
               " where roll.namn = '" + rollNamn + "'");
    }
    
    public ArrayList<String> getFormagorFromRID(int RID) {
        String query = "select formaga.namn from formaga " +
                "join roll_kraver_formaga on formaga.fid=roll_kraver_formaga.fid " + 
                "join roll on roll_kraver_formaga.rid=roll.rid " +
                "where roll.rid = " + RID;
        return SQLSelectList(query);
    }
}
